package cn.iocoder.yudao.module.project.service.orderdetail;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.project.controller.admin.order.vo.OrderPageReqVO;
import cn.iocoder.yudao.module.project.controller.admin.order.vo.OrderRespVO;
import cn.iocoder.yudao.module.project.dal.dataobject.internalcode.InternalCodeDO;
import cn.iocoder.yudao.module.project.dal.dataobject.internalcodeorderedit.InternalCodeOrderEditDO;
import cn.iocoder.yudao.module.project.dal.dataobject.kismaterielexwarehouse.KisMaterielExWarehouseDO;
import cn.iocoder.yudao.module.project.dal.dataobject.kismaterielexwarehouseorderedit.KisMaterielExWarehouseOrderEditDO;
import cn.iocoder.yudao.module.project.dal.dataobject.order.OrderDO;
import cn.iocoder.yudao.module.project.dal.dataobject.productioncode.ProductionCodeDO;
import cn.iocoder.yudao.module.project.dal.dataobject.productioncodeorderedit.ProductionCodeOrderEditDO;
import cn.iocoder.yudao.module.project.dal.dataobject.weighthistory.WeightHistoryDO;
import cn.iocoder.yudao.module.project.dal.dataobject.weighthistoryorderedit.WeightHistoryOrderEditDO;
import cn.iocoder.yudao.module.project.dal.mysql.internalcode.InternalCodeMapper;
import cn.iocoder.yudao.module.project.dal.mysql.internalcodeorderedit.InternalCodeOrderEditMapper;
import cn.iocoder.yudao.module.project.dal.mysql.kismaterielexwarehouse.KisMaterielExWarehouseMapper;
import cn.iocoder.yudao.module.project.dal.mysql.kismaterielexwarehouseorderedit.KisMaterielExWarehouseOrderEditMapper;
import cn.iocoder.yudao.module.project.dal.mysql.order.OrderMapper;
import cn.iocoder.yudao.module.project.dal.mysql.productioncode.ProductionCodeMapper;
import cn.iocoder.yudao.module.project.dal.mysql.productioncodeorderedit.ProductionCodeOrderEditMapper;
import cn.iocoder.yudao.module.project.dal.mysql.weighthistory.WeightHistoryMapper;
import cn.iocoder.yudao.module.project.dal.mysql.weighthistoryorderedit.WeightHistoryOrderEditMapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import cn.iocoder.yudao.module.project.controller.admin.orderdetail.vo.*;
import cn.iocoder.yudao.module.project.dal.dataobject.orderdetail.OrderDetailDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.project.dal.mysql.orderdetail.OrderDetailMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.project.config.projectDefine.HTTP_STATUS.ERROR_STATUS;
import static cn.iocoder.yudao.module.project.enums.ErrorCodeConstants.*;

/**
 * 生产订单详情 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
public class OrderDetailServiceImpl implements OrderDetailService {

    @Resource
    private OrderDetailMapper orderDetailMapper;

    @Resource
    private OrderMapper orderMapper;

    @Resource
    private InternalCodeMapper internalCodeMapper;

    @Resource
    private InternalCodeOrderEditMapper internalCodeOrderEditMapper;

    @Resource
    private KisMaterielExWarehouseMapper kisMaterielExWarehouseMapper;

    @Resource
    private KisMaterielExWarehouseOrderEditMapper kisMaterielExWarehouseOrderEditMapper;

    @Resource
    private ProductionCodeMapper productionCodeMapper;

    @Resource
    private ProductionCodeOrderEditMapper productionCodeOrderEditMapper;

    @Resource
    private WeightHistoryMapper weightHistoryMapper;

    @Resource
    private WeightHistoryOrderEditMapper weightHistoryOrderEditMapper;

    @Override
    public String createOrderDetail(OrderDetailSaveReqVO createReqVO) {
        // 插入
        OrderDetailDO orderDetail = BeanUtils.toBean(createReqVO, OrderDetailDO.class);
        orderDetailMapper.insert(orderDetail);
        // 返回
        return orderDetail.getId();
    }

    @Override
    public void updateOrderDetail(OrderDetailSaveReqVO updateReqVO) {
        // 校验存在
        validateOrderDetailExists(updateReqVO.getId());
        // 更新
        OrderDetailDO updateObj = BeanUtils.toBean(updateReqVO, OrderDetailDO.class);
        orderDetailMapper.updateById(updateObj);
    }

    @Override
    public void deleteOrderDetail(String id) {
        // 校验存在
        validateOrderDetailExists(id);
        // 删除
        orderDetailMapper.delete(new QueryWrapper<OrderDetailDO>().eq("id", id));
    }

    private void validateOrderDetailExists(String id) {
        if (orderDetailMapper.selectById(id) == null) {
            throw exception(ORDER_DETAIL_NOT_EXISTS);
        }
    }

    @Override
    public OrderDetailDO getOrderDetail(String id) {
        return orderDetailMapper.selectById(id);
    }

    @Override
    public PageResult<OrderDetailDO> getOrderDetailPage(OrderDetailPageReqVO pageReqVO) {
        LambdaQueryWrapperX<OrderDO> orderLambdaQueryWrapper = new LambdaQueryWrapperX<>();

        orderLambdaQueryWrapper.likeIfPresent(OrderDO::getArrivalPoint, pageReqVO.getArrivalPoint())
                .eqIfPresent(OrderDO::getId, pageReqVO.getOrderCode())
                .eqIfPresent(OrderDO::getDeliveryMode, pageReqVO.getDeliveryMode())
                .likeIfPresent(OrderDO::getManager, pageReqVO.getManager())
                .likeIfPresent(OrderDO::getBusinessName, pageReqVO.getBusinessName())
                .likeIfPresent(OrderDO::getOperator, pageReqVO.getOperator())
                .likeIfPresent(OrderDO::getRemark, pageReqVO.getRemark())
                .eqIfPresent(OrderDO::getOrderDate, pageReqVO.getOrderDate());
        List<OrderDO> orderDOS = orderMapper.selectList(orderLambdaQueryWrapper);
        if (CollectionUtil.isEmpty(orderDOS)) {
            List<OrderDetailDO> orderDetailDOS = new ArrayList<>();
            PageResult<OrderDetailDO> objectPageResult = new PageResult<>();
            objectPageResult.setList(orderDetailDOS);
            objectPageResult.setTotal(0L);
            return objectPageResult;
        }
        List<String> orderCodes = orderDOS.stream().map(c -> c.getId()).collect(Collectors.toList());
        return orderDetailMapper.selectPage(pageReqVO,orderCodes);
    }




    @Override
    public List<OrderDetailDO> selectSavedList(Map<String, Object> params) {
        List<OrderDetailDO> list = orderDetailMapper.selectSavedList(params);
        return list;
    }

    @Override
    public void insertRecord(List<OrderDetailDO> insertList) {
        // 插入
        if (null != insertList && insertList.size() > 0) {
            //orderDetailMapper.insertList(insertList);
            orderDetailMapper.insertBatch(insertList);
        }
    }

    @Override
    public void updateRecord(List<OrderDetailDO> updateList) {
        // 更新
        if (null != updateList && updateList.size() > 0) {
            LocalDateTime today = LocalDateTimeUtil.now();
            for (OrderDetailDO data : updateList) {
                data.setUpdateTime(today);
            }
            orderDetailMapper.updateList(updateList);
        }
    }

    @Override
    public void editOrderDetail(OrderDetailSaveReqVO updateReqVO) {
        // 校验存在
        validateOrderDetailExists(updateReqVO.getId());

        // 生产订单编号不可修改
        OrderDetailDO orderDetailDO = orderDetailMapper.selectById(updateReqVO.getId());
        if (!updateReqVO.getOrderCode().equals(orderDetailDO.getOrderCode())) {
            throw new ServiceException(ERROR_STATUS, "生产订单编号不可修改");
        }

        if(updateReqVO.getNum().longValue() != updateReqVO.getOldnum().longValue()){
            // 更新
            OrderDetailDO updateObj = BeanUtils.toBean(updateReqVO, OrderDetailDO.class);
            orderDetailMapper.updateById(updateObj);

            String orderCode = updateObj.getOrderCode();
            // 删除相关内码
            List<InternalCodeDO> internalCodeDOS = internalCodeMapper.selectList("order_code", orderCode);
            if (CollectionUtil.isNotEmpty(internalCodeDOS)) {
                List<InternalCodeOrderEditDO> internalCodeOrderEditDOS = new ArrayList<>();
                for (InternalCodeDO internalCodeDO : internalCodeDOS) {
                    InternalCodeOrderEditDO internalCodeOrderEditDO = BeanUtils.toBean(internalCodeDO, InternalCodeOrderEditDO.class);
                    internalCodeOrderEditDO.setInternalCodeId(internalCodeDO.getId());
                    internalCodeOrderEditDOS.add(internalCodeOrderEditDO);
                }
                internalCodeOrderEditMapper.insertBatch(internalCodeOrderEditDOS);
                internalCodeMapper.delete("order_code", orderCode);
            }

            // 删除相关物料出库单
            List<KisMaterielExWarehouseDO> kisMaterielExWarehouseDOS = kisMaterielExWarehouseMapper.selectList("order_code", orderCode);
            if (CollectionUtil.isNotEmpty(kisMaterielExWarehouseDOS)) {
                ArrayList<KisMaterielExWarehouseOrderEditDO> kisMaterielExWarehouseOrderEditDOS = new ArrayList<>();
                for (KisMaterielExWarehouseDO kisMaterielExWarehouseDO : kisMaterielExWarehouseDOS) {
                    KisMaterielExWarehouseOrderEditDO kisMaterielExWarehouseOrderEditDO = BeanUtils.toBean(kisMaterielExWarehouseDO, KisMaterielExWarehouseOrderEditDO.class);
                    kisMaterielExWarehouseOrderEditDO.setExWarehouseId(kisMaterielExWarehouseDO.getId());
                    kisMaterielExWarehouseOrderEditDOS.add(kisMaterielExWarehouseOrderEditDO);
                }
                kisMaterielExWarehouseOrderEditMapper.insertBatch(kisMaterielExWarehouseOrderEditDOS);
                kisMaterielExWarehouseMapper.delete("order_code", orderCode);
            }

            // 删除相关成品码
            List<ProductionCodeDO> productionCodeDOS = productionCodeMapper.selectList("order_code", orderCode);
            if (CollectionUtil.isNotEmpty(productionCodeDOS)) {
                List<ProductionCodeOrderEditDO> productionCodeOrderEditDOS = new ArrayList<>();
                for (ProductionCodeDO productionCodeDO : productionCodeDOS) {
                    ProductionCodeOrderEditDO productionCodeOrderEditDO = BeanUtils.toBean(productionCodeDO, ProductionCodeOrderEditDO.class);
                    productionCodeOrderEditDO.setProductId(productionCodeDO.getId());
                    productionCodeOrderEditDOS.add(productionCodeOrderEditDO);
                }
                productionCodeOrderEditMapper.insertBatch(productionCodeOrderEditDOS);
                productionCodeMapper.delete("order_code", orderCode);
            }

            // 删除相关称重业务
            List<WeightHistoryDO> weightHistoryDOS = weightHistoryMapper.selectList("order_code", orderCode);
            if (CollectionUtil.isNotEmpty(weightHistoryDOS)) {
                List<WeightHistoryOrderEditDO> weightHistoryOrderEditDOS = new ArrayList<>();
                for (WeightHistoryDO weightHistoryDO : weightHistoryDOS) {
                    WeightHistoryOrderEditDO weightHistoryOrderEditDO = BeanUtils.toBean(weightHistoryDO, WeightHistoryOrderEditDO.class);
                    weightHistoryOrderEditDO.setWeightId(weightHistoryDO.getId());
                    weightHistoryOrderEditDOS.add(weightHistoryOrderEditDO);
                }
                weightHistoryOrderEditMapper.insertBatch(weightHistoryOrderEditDOS);
                weightHistoryMapper.delete("order_code", orderCode);
            }
        }else{
            OrderDetailDO updateObj = BeanUtils.toBean(updateReqVO, OrderDetailDO.class);
            orderDetailMapper.updateById(updateObj);
        }



    }

    @Override
    public PageResult<OrderDetailDO> selectOrderDetailPage(OrderDetailPageReqVO pageReqVO) {
        Page<OrderDetailPageReqVO> page = new Page(pageReqVO.getPageNo(), pageReqVO.getPageSize());
        if(pageReqVO.getDeliveryDate() != null && pageReqVO.getDeliveryDate().length == 2){
            String[] dateArr = pageReqVO.getDeliveryDate();
            pageReqVO.setStartDate(dateArr[0] + " 00:00:00").setEndDate(dateArr[1] + " 23:59:59");
        }

        List<OrderDetailDO> list = orderDetailMapper.selectOrderDetailPage(page, pageReqVO);
        PageResult<OrderDetailDO> pageResult = new PageResult<>(list, page.getTotal());
        return pageResult;
    }


    @Override
    public List<String> queryOrderFlexList(String orderCode){
        List<OrderDetailDO> orderDetailDOList = orderDetailMapper.selectList(OrderDetailDO::getOrderCode, orderCode);
        return orderDetailDOList.stream().map(OrderDetailDO::getFlex).map(item -> item.substring(0, 6)).distinct().collect(Collectors.toList());
    }
}